【图文解析】反转一个单链表

您所在的位置:网站首页 go 链表反转 【图文解析】反转一个单链表

【图文解析】反转一个单链表

2023-10-18 23:40| 来源: 网络整理| 查看: 265

目录 例题描述💡 思路一 (推荐)代码实现 💡 思路二代码实现 引申1. 局部反转单链表2. k个一组反转链表

例题描述

反转一个链表

示例:

输入: 1->2->3->4->5->NULL输出: 5->4->3->2->1->NULL

结构体定义

struct ListNode { int val; struct ListNode *next; };

在这里插入图片描述

💡 思路一 (推荐)

先对原链表做头删操作,再对新链表做头插

定义一个新head头指针,标记为newHead,将它初始为NULL,并非指向NULL,最后我们选择返回这个newHead指针作为新链表的头指针。 在这里插入图片描述定义一个结点node作为"临时中转站",初始化与否并无大影响。进行循环遍历链表各个结点,判定head指针是否为空,即是否到达了原链表的结尾。如果不为空,说明还没有到达尾部。如果程序第一次运行就没有进入循环,说明传入了一个空链表,此时返回newHead新链表的头指针,同样返回NULL,这样处理也是合理的。以下开始逆序链表逻辑:在当前指针不为NULL时,先对原链表做头删操作,再对新链表做头插操作。即使用循环进行操作:让node指针指向传入函数链表的头指针head,两指针指向保持相同。 在这里插入图片描述然后让head指针指向它的next结点,此时旧链表已经完成了头删操作。第一个结点已经被"切割"下来。接下来要做的就是对新链表进行头插操作,使结点放入新链表。 在这里插入图片描述让node指针的next下一个结点指向新链表的头指针newHead,完成结点的链接,即头插入新的链表中。然后更新newHead指向为新链表的头结点。进行下一次循环。 在这里插入图片描述8. 最终head指针指向了原链表的结尾,即为NULL,退出循环,此时新链表已经反转完毕,情况如图: 在这里插入图片描述最终返回新链表头指针newHead即可。 代码实现 struct ListNode *reverseList(struct ListNode* head) { struct ListNode *newHead = NULL; struct ListNode *node; while (head != NULL) { //1. 对之前的链表做头删 node = head; head = head->next; //2. 对新链表做头插 node->next = newHead; newHead = node; } return newHead; } 💡 思路二 利用选择语句,找到空链表的情况,此情况返回NULL空指针,因为空链表不能反转,或者说反转之后还是一个空链表,返回空。利用三个指针p0"前指针"、p1"当前指针"、p2"后指针"来分批处理链表元素,p0置为NULL,它将作为链表的尾结点向前推进处理,p1指向旧链表的头指针head,p2指向旧链表的头指针的next结点。 在这里插入图片描述开始遍历链表,循环判定因子为p1,当它为空时到达链表尾部跳出循环。否则在表中执行循环内逻辑:将p1指向的当前结点的下一个结点指向p0,即前一个结点。 此时p0为NULL,那么p1的下一个结点就为空了,它现在是最后一个结点。 在这里插入图片描述然后将p0指针指向p1,将p1指针指向p2,注意这两步不可以调换顺序,否则正确向后挪移一位。此时完成了三个指针的一轮更迭。判定p2指针是否为空,如果为空说明此时p2到达了链表结尾,当前指针p1的指向为最后一个结点,它的next即为空。如果不为空,将p2更新到下一个结点,进行下一次循环。 在这里插入图片描述下一次进行循环时,就会把截断结点链接到新链表的头部,同时更新三个指针。继续循环。 在这里插入图片描述循环终止条件为:p1指向了链表尾部的NULL,此时p1的前指针p0即指向了反转后的链表,它就是新链表的head头指针。此时返回p0即可。 代码实现 struct ListNode *reverseList(struct ListNode* head) { if (head == NULL) { return NULL; } struct ListNode *p0 = NULL; struct ListNode *p1 = head; struct ListNode *p2 = head->next; while (p1 != NULL) { p1->next = p0; p0 = p1; p1 = p2; if (p2 != NULL) { p2 = p2->next; } } return p0; } 引申

好的,至此你学会了单链表整体反转的简单实现,实操中要求程序员具备举一反三的能力,以下列出2种针对此题目的衍生问题。

一是并非整个单链表反转,而是指定链表的某一段区间进行反转,即局部反转链表。二是k个一组反转链表,顾名思义,例如每两个节点反转一次,操作整个链表完成处理。

有兴趣了解引申题目的同学可以移步以下博文:

1. 局部反转单链表

点击这里跳转:https://blog.csdn.net/qq_42351880/article/details/123615424

2. k个一组反转链表

点击这里跳转:https://blog.csdn.net/qq_42351880/article/details/123612673



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3